#include "ChessDatabase.h"
#include <stdexcept>
#include <iostream>

ChessDatabase::ChessDatabase(const std::string& db_path) {
    if (sqlite3_open(db_path.c_str(), &db) != SQLITE_OK) {
        throw std::runtime_error("无法打开数据库: " + std::string(sqlite3_errmsg(db)));
    }
    create_table();
}

ChessDatabase::~ChessDatabase() {
    sqlite3_close(db);
}

void ChessDatabase::create_table() {
    const char* sql = R"(
            CREATE TABLE IF NOT EXISTS chess_pieces (
                num INTEGER PRIMARY KEY AUTOINCREMENT,  -- 自动递增的主键
                x REAL NOT NULL,
                y REAL NOT NULL,
                color TEXT CHECK(color IN ('red', 'black')),
                type TEXT NOT NULL,
                hu1 REAL NOT NULL,
                hu2 REAL NOT NULL,
                hu3 REAL NOT NULL,
                hu4 REAL NOT NULL,
                hu5 REAL NOT NULL,
                hu6 REAL NOT NULL,
                hu7 REAL NOT NULL
            );
        )";

        char* errMsg = nullptr;
        if (sqlite3_exec(db, sql, nullptr, nullptr, &errMsg) != SQLITE_OK) {
            std::string error = "创建表失败: " + std::string(errMsg);
            sqlite3_free(errMsg);
            throw std::runtime_error(error);
        }
}

void ChessDatabase::addChessPiece(const ChessPiece& piece) {
     const char* sql = "INSERT INTO chess_pieces (x, y, color, type, hu1, hu2, hu3, hu4, hu5, hu6, hu7) "
            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";

        sqlite3_stmt* stmt;
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
            throw std::runtime_error("准备SQL语句失败");
        }

        // 绑定参数（省略 num，因为它是自动递增的）
        sqlite3_bind_double(stmt, 1, piece.x);
        sqlite3_bind_double(stmt, 2, piece.y);
        sqlite3_bind_text(stmt, 3, piece.color.c_str(), -1, SQLITE_STATIC);
        sqlite3_bind_text(stmt, 4, piece.type.c_str(), -1, SQLITE_STATIC);

        for (int i = 0; i < 7; ++i) {
            sqlite3_bind_double(stmt, 5 + i, piece.huMoments[i]);
        }

        if (sqlite3_step(stmt) != SQLITE_DONE) {
            sqlite3_finalize(stmt);
            throw std::runtime_error("插入数据失败: " + std::string(sqlite3_errmsg(db)));
        }

        sqlite3_finalize(stmt);
}

void ChessDatabase::printAllChessPieces() {
       const char* sql = "SELECT num, x, y, color, type, hu1, hu2, hu3, hu4, hu5, hu6, hu7 FROM chess_pieces;";
        sqlite3_stmt* stmt;

        if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
            throw std::runtime_error("准备查询语句失败");
        }

        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int num = sqlite3_column_int(stmt, 0);
            double x = sqlite3_column_double(stmt, 1);
            double y = sqlite3_column_double(stmt, 2);
            const char* color = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
            const char* type = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 4));

            std::array<double, 7> huMoments;
            for (int i = 0; i < 7; ++i) {
                huMoments[i] = sqlite3_column_double(stmt, 5 + i);
            }

            // 打印结果
            std::cout << "num: " << num << ", x: " << x << ", y: " << y
                      << ", color: " << color << ", type: " << type << std::endl;
            std::cout << "Hu Moments: ";
            for (double hu : huMoments) {
                std::cout << hu << " ";
            }
            std::cout << std::endl;
        }

        sqlite3_finalize(stmt);
}

std::string ChessDatabase::matchChessPiece(const ChessPiece& piece) {
const char* sql = "SELECT type, hu1, hu2, hu3, hu4, hu5, hu6, hu7 FROM chess_pieces WHERE color = ?;";
    sqlite3_stmt* stmt;
 
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        throw std::runtime_error("准备查询语句失败");
    }
 
    // 绑定颜色参数
    sqlite3_bind_text(stmt, 1, piece.color.c_str(), -1, SQLITE_STATIC);
 
    std::string bestType;
    double minDistance = std::numeric_limits<double>::max();
    int matchCount = 0;
 
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        const char* type = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
        std::array<double, 7> dbHuMoments;
        
        // 提取数据库中的Hu矩
        for (int i = 0; i < 7; ++i) {
            dbHuMoments[i] = sqlite3_column_double(stmt, 1 + i);
        }
 
        // 计算欧氏距离
        double distance = 0.0;
        for (int i = 0; i < 7; ++i) {
            double diff = piece.huMoments[i] - dbHuMoments[i];
            distance += diff * diff;
        }
        distance = sqrt(distance);
 
        // 更新最佳匹配
        if (distance < minDistance) {
            minDistance = distance;
            bestType = type;
        }
        matchCount++;
    }
 
    sqlite3_finalize(stmt);
 
    if (matchCount == 0) {
        throw std::runtime_error("未找到同颜色棋子记录");
    }
 
    return bestType;
}